package com.ruoyi.asms.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.ams.controller.AmsAssetTypeController;
import com.ruoyi.asms.domain.AsmsMaintenanceAsset;
import com.ruoyi.asms.domain.vo.AssetFullInfoExportVo;
import com.ruoyi.asms.domain.vo.AssetFullInfoImportVo;
import com.ruoyi.asms.domain.vo.InspectionAssetTypeSearchVo;
import com.ruoyi.asms.service.*;
import com.ruoyi.common.core.domain.*;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.vo.AssetInfoVo;
import com.ruoyi.common.core.exception.GlobalException;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.SecurityUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.security.annotation.PreAuthorize;
import com.ruoyi.security.service.TokensService;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * @Description
 * @Author YangJun
 * @Date 2021年11月22日 13:46:12
 **/
@RestController
@RequestMapping("/asms/AsmsAssetFullInfo")
public class AsmsAssetFullInfoController extends BaseController {
    @Autowired
    private IAsmsAssetFullInfoService asmsAssetFullInfoService;
    @Autowired
    private AsmsReusingService asmsReusingService;
//    @Autowired
//    private RemoteAssetTypeService remoteAssetTypeService;
//    @Autowired
//    private RemoteAssetInfoService remoteAssetInfoService;
//    @Autowired
//    private RemoteDeptService remoteDeptService;
//    @Autowired
//    private RemoteUserService remoteUserService;
//    @Autowired
//    private RemoteAssetAddressService remoteAssetAddressService;
//    @Autowired
//    private RemoteIotService remoteIotService;

    @Autowired
    AmsAssetTypeController amsAssetTypeController;
    @Autowired
    private TokensService tokenService;
    @Autowired
    private IAsmsOwnMaintenanceDeptService asmsOwnMaintenanceDeptService;
    @Autowired
    private IAsmsMaintenanceAssetService asmsMaintenanceAssetService;
    @Autowired
    private IAsmsOwnAddressAssetCodeService asmsOwnAddressAssetCodeService;


    @GetMapping("/getAmsUserName")
    public AjaxResult getAmsUserName() {
        return AjaxResult.success(asmsReusingService.getAmsUserName());
    }
    /**
     * 查询资产详细信息列表
     * ，按3个维度展示：1、资产基本信息（名称、型号、类型、编码、品牌、批次）。\n" +
     * "2、资产所有方信息(所有方使用部门、使用人员、位置、状态、时间信息)。\n" +
     * "3、资产维护方信息(维护方售后维护模块开发后再做)
     */
    //@PreAuthorize
    @GetMapping("/list")
    @ApiOperation(value = "资产列表信息", response = AsmsAssetFullInfo.class)
    public TableDataInfo list(AssetInfoView assetInfoView) {
        QueryWrapper<AsmsAssetFullInfo> wrapper = new QueryWrapper<>();
        if (assetInfoView.getUserId() != null) {
            wrapper.eq(AsmsAssetFullInfo.USER_ID, assetInfoView.getUserId());
        }
        if (assetInfoView.getAssetSource() != null) {
            wrapper.eq(AsmsAssetFullInfo.ASSET_SOURCE, assetInfoView.getAssetSource());
        }
        if (assetInfoView.getAssetStatus() != null) {
            wrapper.eq(AsmsAssetFullInfo.ASSET_STATUS, assetInfoView.getAssetStatus());
        }
        if (assetInfoView.getBrandId() != null) {
            wrapper.eq(AsmsAssetFullInfo.BRAND_ID, assetInfoView.getBrandId());
        }
        if (assetInfoView.getAssetTemplateId() != null) {
            wrapper.eq(AsmsAssetFullInfo.ASSET_TEMPLATE_ID, assetInfoView.getAssetTemplateId());
        }
        if (assetInfoView.getAssetTypeId() != null) {
            wrapper.eq(AsmsAssetFullInfo.ASSET_TYPE_ID, assetInfoView.getAssetTypeId());
        }
        if (assetInfoView.getAddressId() != null) {
            wrapper.eq(AsmsAssetFullInfo.ADDRESS_ID, assetInfoView.getAddressId());
        }
        if (assetInfoView.getOwnDeptId() != null) {
            wrapper.eq(AsmsAssetFullInfo.OWN_DEPT_ID, assetInfoView.getOwnDeptId());
        }
        if (assetInfoView.getAssetTypeName() != null) {
            wrapper.like(AsmsAssetFullInfo.ASSET_TYPE_NAME, assetInfoView.getAssetTypeName());
        }
        if (StringUtils.isNotEmpty(assetInfoView.getAssetCode()) ) {
            wrapper.eq(AsmsAssetFullInfo.ASSET_CODE, assetInfoView.getAssetCode());
        }
        if (StringUtils.isNotEmpty(assetInfoView.getSn()) ) {
            wrapper.eq(AsmsAssetFullInfo.SN, assetInfoView.getSn());
        }



        wrapper.orderByDesc(AsmsAssetFullInfo.CREATE_TIME);

        //系统管理员查看所有资产、部门负责人查看本部门拥有的资产
        if (!SysUser.isAdmin(SecurityUtils.getUserId())&&assetInfoView.getType()!=null) {
            if(assetInfoView.getType()==1){
                Set<Long> userOwnDeptIds = tokenService.getUserOwnDeptIds();
                if (userOwnDeptIds != null && userOwnDeptIds.size() > 0) {
                    wrapper.in(AsmsAssetFullInfo.OWN_DEPT_ID, userOwnDeptIds);
                }
            }
            if(assetInfoView.getType()==2) {
                Set<Long> userMDeptIds = tokenService.getUserMaintenanceDeptIds();
                if (userMDeptIds != null && userMDeptIds.size() > 0) {
                    wrapper.in(AsmsAssetFullInfo.MAINTENANCE_DEPT_ID, userMDeptIds);
                }
            }
        }
        startPage();
        List<AsmsAssetFullInfo> lst = asmsAssetFullInfoService.list(wrapper);
        return getDataTable(lst);
    }

    @ApiOperation("导出，可根据筛选条件导出")
    @PostMapping(value="/export", produces = "application/octet-stream")
    public void export(HttpServletResponse response, AsmsAssetFullInfo asmsAssetFullInfo) throws Exception {
        QueryWrapper<AsmsAssetFullInfo> wrapper = new QueryWrapper<>();
        if (asmsAssetFullInfo.getUserId() != null) {
            wrapper.eq(AsmsAssetFullInfo.USER_ID, asmsAssetFullInfo.getUserId());
        }
        if (asmsAssetFullInfo.getBrandId() != null) {
            wrapper.eq(AsmsAssetFullInfo.BRAND_ID, asmsAssetFullInfo.getBrandId());
        }
        if (asmsAssetFullInfo.getAssetStatus() != null) {
            wrapper.eq(AsmsAssetFullInfo.ASSET_STATUS, asmsAssetFullInfo.getAssetStatus());
        }
        if (asmsAssetFullInfo.getAssetTypeId() != null) {
            wrapper.eq(AsmsAssetFullInfo.ASSET_TYPE_ID, asmsAssetFullInfo.getAssetTypeId());
        }
        if (asmsAssetFullInfo.getAssetTemplateId() != null) {
            wrapper.eq(AsmsAssetFullInfo.ASSET_TEMPLATE_ID, asmsAssetFullInfo.getAssetTemplateId());
        }
        if (asmsAssetFullInfo.getAddressId() != null) {
            wrapper.eq(AsmsAssetFullInfo.ADDRESS_ID, asmsAssetFullInfo.getAddressId());
        }
        wrapper.orderByDesc(AsmsAssetFullInfo.ASSET_ID);
        //系统管理员查看所有资产、部门负责人查看本部门拥有的资产

        if (!SysUser.isAdmin(SecurityUtils.getUserId())) {
            Set<Long> userOwnDeptIds = tokenService.getUserOwnDeptIds();
            Set<Long> maintenanceDeptIds = tokenService.getUserMaintenanceDeptIds();
            if (userOwnDeptIds != null && userOwnDeptIds.size() > 0) {
                wrapper.in(AsmsAssetFullInfo.OWN_DEPT_ID, userOwnDeptIds);
                if (maintenanceDeptIds != null && maintenanceDeptIds.size() > 0) {
                    wrapper.or().in(AsmsAssetFullInfo.MAINTENANCE_DEPT_ID, maintenanceDeptIds);
                }
            }
            if (maintenanceDeptIds != null && maintenanceDeptIds.size() > 0) {
                wrapper.in(AsmsAssetFullInfo.MAINTENANCE_DEPT_ID, maintenanceDeptIds);
                if (userOwnDeptIds != null && userOwnDeptIds.size() > 0) {
                    wrapper.or().in(AsmsAssetFullInfo.OWN_DEPT_ID, userOwnDeptIds);
                }
            }
        }
        //
        List<AsmsAssetFullInfo> list = asmsAssetFullInfoService.list(wrapper);
        if (list.size() == 0) {
            throw new GlobalException("没有资产！");
        }
        List<AssetFullInfoExportVo> vos = new ArrayList<>();
        list.forEach(item -> {
            AssetFullInfoExportVo vo = new AssetFullInfoExportVo();
            BeanUtils.copyProperties(item, vo);
            vos.add(vo);
        });
        ExcelUtil<AssetFullInfoExportVo> util = new ExcelUtil<AssetFullInfoExportVo>(AssetFullInfoExportVo.class);
        util.exportExcel(response, vos, "资产售后维护信息数据");
    }

    private List<List<AssetFullInfoImportVo>> splitList(List<AssetFullInfoImportVo> messagesList, int groupSize) {
        int length = messagesList.size();
        // 计算可以分成多少组
        int num = (length + groupSize - 1) / groupSize; // TODO
        List<List<AssetFullInfoImportVo>> newList = new ArrayList<>(num);
        for (int i = 0; i < num; i++) {
            // 开始位置
            int fromIndex = i * groupSize;
            // 结束位置
            int toIndex = Math.min((i + 1) * groupSize, length);
            newList.add(messagesList.subList(fromIndex, toIndex));
        }
        return newList;
    }

    @ApiOperation("导入，根据模板文件导入")
    @PostMapping("/importOld")
    @ResponseBody
    @PreAuthorize
    public AjaxResult importOld(MultipartFile file) {

        ExcelUtil<AssetFullInfoImportVo> util = new ExcelUtil<AssetFullInfoImportVo>(AssetFullInfoImportVo.class);
        List<AssetFullInfoImportVo> list = null;
        try {
            list = util.importExcel(file.getInputStream());
        } catch (Exception e) {
        }
        //拆分大list
        if(list==null) return success();
        List<List<AssetFullInfoImportVo>> lists = splitList(list, 500);
        for (List<AssetFullInfoImportVo> item : lists) {
            AjaxResult ajaxResult = asmsReusingService.importAssetInfo(item);
            Integer code = (Integer) ajaxResult.get("code");
            String msg = (String) ajaxResult.get("msg");
            String startSn = item.get(0).getSn();
            String endSn = item.get(item.size()-1).getSn();
            if(500 ==code){
                return error("从"+startSn+'到'+endSn+"的资产导入失败"+msg);
            }else {
                System.out.println("导入成功+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
                System.out.println("从"+startSn+'到'+endSn+"的资产导入成功！");
                System.out.println("导入成功+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
            }
        }
        return success();
    }

    @ApiOperation("导入，根据模板文件导入")
    @PostMapping("/import")
    @ResponseBody
    @PreAuthorize
    public AjaxResult importDataR(MultipartFile file) {

        ExcelUtil<AssetFullInfoImportVo> util = new ExcelUtil<AssetFullInfoImportVo>(AssetFullInfoImportVo.class);
        List<AssetFullInfoImportVo> list = null;
        try {
            list = util.importExcel(file.getInputStream());
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return AjaxResult.error("解析Excel出现错误，请确定数据是否为空并是否按照要求填写！");
        }

        return asmsReusingService.importAssetInfo(list);
    }

    @ApiOperation("导入，根据模板文件导入")
    //@PostMapping("/import")
    @ResponseBody
    public AjaxResult importData(MultipartFile file) {
        Calendar calendar = Calendar.getInstance();
        int i = calendar.get(Calendar.SECOND);
        if ((i & 1) == 1) {
            return AjaxResult.success("上传成功，请刷新页面");
        } else {
            return AjaxResult.success("上传失败，提示错误原因，很长一串错误原因\n提示错误原因，很长一串错误原因\n提示错误原因，很长一串错误原因\n提示错误原因，很长一串错误原因\n提示错误原因，很长一串错误原因\n提示错误原因，很长一串错误原因\n提示错误原因，很长一串错误原因\n");
        }
    }

    @ApiOperation("用户获取维护商维护的资产批次名称用于选择")
    @GetMapping("/getMaintenanceDeptProjectNamesForSelect")
    public R<List<KeyValueVo>> getMaintenanceDeptProjectNamesForSelect
            (@ApiParam(name = "maintenanceDeptId", value = "新增时传登录用户的部门Id，修改时传任务的maintenanceDeptId") Long maintenanceDeptId) {
        List<KeyValueVo> vos = new ArrayList<>();
        final List<AsmsAssetFullInfo> list = asmsAssetFullInfoService.list(new QueryWrapper<AsmsAssetFullInfo>()
                .eq(AsmsAssetFullInfo.MAINTENANCE_DEPT_ID, maintenanceDeptId)
                .groupBy(AsmsAssetFullInfo.PROJECT_ID)
                .orderByDesc(AsmsAssetFullInfo.CREATE_TIME).select(AsmsAssetFullInfo.PROJECT_ID, AsmsAssetFullInfo.PROJECT_NAME));

        for (AsmsAssetFullInfo fullInfo : list) {
            if (fullInfo != null) {
                KeyValueVo vo = new KeyValueVo();
                vo.setKey(fullInfo.getProjectId());
                vo.setValue(fullInfo.getProjectName());
                vos.add(vo);
            }
        }
        return R.ok(vos);
    }

    @ApiOperation("获取维护商维护的客户列表用于选择")
    @GetMapping("/getMaintenanceOwnDeptNamesForSelect")
    public R<List<KeyValueVo>> getMaintenanceOwnDeptNamesForSelect
            (@ApiParam(name = "maintenanceDeptId", value = "新增时传登录用户的部门Id，修改时传任务的maintenanceDeptId") Long maintenanceDeptId,
             @ApiParam(name = "projectIds", value = "选择的批次主键数组") Long[] projectIds) {
        //获取用户部门的所有子部门
        List<KeyValueVo> vos = new ArrayList<>();

        QueryWrapper<AsmsAssetFullInfo> queryWrapper = new QueryWrapper<AsmsAssetFullInfo>();
        queryWrapper
                .eq(AsmsAssetFullInfo.MAINTENANCE_DEPT_ID, maintenanceDeptId)
                .groupBy(AsmsAssetFullInfo.OWN_DEPT_ID)
                .orderByDesc(AsmsAssetFullInfo.CREATE_TIME)
                .select(AsmsAssetFullInfo.OWN_DEPT_ID, AsmsAssetFullInfo.OWN_DEPT_NAME);
        if (ArrayUtils.isNotEmpty(projectIds)) {
            projectSelectWrapper(queryWrapper, projectIds);
        }
        final List<AsmsAssetFullInfo> list = asmsAssetFullInfoService.list(queryWrapper);

        for (AsmsAssetFullInfo fullInfo : list) {
            if (fullInfo != null) {
                KeyValueVo vo = new KeyValueVo();
                vo.setKey(fullInfo.getOwnDeptId());
                vo.setValue(fullInfo.getOwnDeptName());
                vos.add(vo);
            }
        }

        return R.ok(vos);
    }

    @ApiOperation("获取维护商安装绑定人员列表")
    @GetMapping("/getMaintenanceDeptBindUserNamesForSelect")
    public R<List<KeyValueVo>> getMaintenanceDeptBindUserNamesForSelect
            (@ApiParam(name = "maintenanceDeptId", value = "新增时传登录用户的部门Id，修改时传任务的maintenanceDeptId") Long maintenanceDeptId
                    , @ApiParam(name = "projectIds", value = "选择的批次主键数组") Long[] projectIds
                    , @ApiParam(name = "assetOwnIds", value = "选择的客户主键数组") Long[] assetOwnIds
                    , @ApiParam(name = "addressIds", value = "选择的区域主键数组") Long[] addressIds
            ) {
        List<KeyValueVo> vos = new ArrayList<>();
        QueryWrapper<AsmsAssetFullInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq(AsmsAssetFullInfo.MAINTENANCE_DEPT_ID, maintenanceDeptId)
                .groupBy(AsmsAssetFullInfo.BIND_USER_ID)
                .orderByDesc(AsmsAssetFullInfo.CREATE_TIME).select(AsmsAssetFullInfo.BIND_USER_ID, AsmsAssetFullInfo.BIND_USER_NAME);
        if (ArrayUtils.isNotEmpty(projectIds)) {
            projectSelectWrapper(queryWrapper, projectIds);
        }
        if (ArrayUtils.isNotEmpty(assetOwnIds)) {
            ownDeptSelectWrapper(queryWrapper, assetOwnIds);
        }
        if (ArrayUtils.isNotEmpty(addressIds)) {
            addressSelectWrapper(queryWrapper, addressIds);
        }
        final List<AsmsAssetFullInfo> list = asmsAssetFullInfoService.list(queryWrapper);
        for (AsmsAssetFullInfo fullInfo : list) {
            if (fullInfo != null) {
                KeyValueVo vo = new KeyValueVo();
                vo.setKey(fullInfo.getBindUserId());
                vo.setValue(fullInfo.getBindUserName());
                vos.add(vo);
            }
        }
        return R.ok(vos);
    }

    @ApiOperation("根据筛选条件筛选资产类型树表")
    @PostMapping("/getAssetTypeTreeSelectByCondition")
    public R<List<TreeSelect>> getAssetTypeTreeSelectByCondition(@RequestBody InspectionAssetTypeSearchVo vo) {
        QueryWrapper<AsmsAssetFullInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(AsmsAssetFullInfo.MAINTENANCE_DEPT_ID, vo.getMaintenanceDeptId());
        if (vo.getBindStartTime() != null && vo.getBindStartTime() > 0) {
            queryWrapper.ge(AsmsAssetFullInfo.BIND_TIME, vo.getBindStartTime());
        }
        if (vo.getBindEndTime() != null && vo.getBindEndTime() > 0) {
            queryWrapper.le(AsmsAssetFullInfo.BIND_TIME, vo.getBindEndTime());
        }
        if (ArrayUtils.isNotEmpty(vo.getAddressIds())) {
            addressSelectWrapper(queryWrapper, vo.getAddressIds());
        }
        if (ArrayUtils.isNotEmpty(vo.getAssetBindUserIds())) {
            bindUserSelectWrapper(queryWrapper, vo.getAssetBindUserIds());
        }
        if (ArrayUtils.isNotEmpty(vo.getAssetOwnIds())) {
            ownDeptSelectWrapper(queryWrapper, vo.getAssetOwnIds());
        }
        if (ArrayUtils.isNotEmpty(vo.getProjectIds())) {
            projectSelectWrapper(queryWrapper, vo.getProjectIds());
        }
        queryWrapper.groupBy(AsmsAssetFullInfo.ASSET_TYPE_ID).select(AsmsAssetFullInfo.ASSET_TYPE_ID, AsmsAssetFullInfo.ASSET_TYPE_ANCESTORS);
        final List<AsmsAssetFullInfo> list = asmsAssetFullInfoService.list(queryWrapper);
        Set<Long> topTypeIds = new HashSet<>();
        Set<Long> typeIds = new HashSet<>();
        if (list.size() == 0) {
            return R.ok(new ArrayList<TreeSelect>());
        }
        list.forEach(item -> {
            typeIds.add(item.getAssetTypeId());
            String ancestors = item.getAssetTypeAncestors();
            Long topTypeId = item.getAssetTypeId();
            if (ancestors != null && !ancestors.equals("0")) {
                Long[] deptIds = Convert.toLongArray(ancestors);
                topTypeId = deptIds[1];
            }
            topTypeIds.add(topTypeId);
        });
        R<List<TreeSelect>> rTreeSelect = amsAssetTypeController.treeSelectByTypeIds(topTypeIds.toArray(new Long[0]));
        if (R.FAIL == rTreeSelect.getCode()) {
            throw new ServiceException(rTreeSelect.getMsg());
        }

        List<TreeSelect> treeSelects = rTreeSelect.getData();
        if (treeSelects == null) {
            return R.ok(new ArrayList<TreeSelect>());
        }
        rTreeSelect.getData().removeIf(treeSelect -> findTreeSelectNext(treeSelect, typeIds));
        //treeSelects.removeIf(treeSelect -> findTreeSelectNext(treeSelect, typeIds));

        return R.ok(treeSelects);
    }

    /**
     * 定时任务查所有的资产数据用户处理
     * @return
     */
    @GetMapping("/getAllAssetInfoTask")
    public R<List<AsmsAssetFullInfo>> getAllAssetInfoTask(@RequestParam("startTime") Long startTime) {
        //全部,后期需要考虑查询优化，定时任务为单独模块考虑查询效率的必要性不大
        List<AsmsAssetFullInfo> viewList = asmsAssetFullInfoService.list(new QueryWrapper<AsmsAssetFullInfo>().gt(AsmsAssetFullInfo.UPDATE_TIME,startTime));
        for (AsmsAssetFullInfo asmsAssetFullInfo : viewList) {
            asmsAssetFullInfo.setBindTimeStr(DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD,asmsAssetFullInfo.getBindTime()));
            String assetSource="";
            if(asmsAssetFullInfo.getAssetSource()!=null){
                switch (asmsAssetFullInfo.getAssetSource()){
                    case "1":assetSource= "购入"; break;
                    case "2":assetSource= "自建"; break;
                    case "3":assetSource= "租赁"; break;
                    case "4":assetSource= "捐赠"; break;
                    case "5":assetSource= "内部购入"; break;
                    case "6":assetSource= "盘盈"; break;
                    default:assetSource= "其他";
                }
            }
            asmsAssetFullInfo.setAssetSourceStr(assetSource);
            String assetStatus="";
            if(asmsAssetFullInfo.getAssetStatus()!=null){
                switch (asmsAssetFullInfo.getAssetStatus()){
                    case "1":assetStatus= "在用"; break;
                    case "2":assetStatus= "借用"; break;
                    case "3":assetStatus= "报废"; break;
                    case "4":assetStatus= "调拨中"; break;
                    case "5":assetStatus= "维修中"; break;
                    default:assetStatus= "其他";
                }
            }

            asmsAssetFullInfo.setAssetStatusStr(assetStatus);
            asmsAssetFullInfo.setStartUseTimeStr(DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD,asmsAssetFullInfo.getStartUseTime()));
            asmsAssetFullInfo.setEndUseTimeStr(DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD,asmsAssetFullInfo.getEndUseTime()));
            asmsAssetFullInfo.setIsDeleteStr(asmsAssetFullInfo.getIsDelete()==0?"删除":"正常");
        }
        return R.ok(viewList);
    }


    private Boolean findTreeSelectNext(TreeSelect tree, Set<Long> typeIds) {
        AtomicBoolean isNeedRemove = new AtomicBoolean(true);
        if (tree.getChildren() != null && tree.getChildren().size() > 0) {
            Iterator<TreeSelect> iterator = tree.getChildren().iterator();
            while (iterator.hasNext()) {
                if (findTreeSelectNext(iterator.next(), typeIds)) {
                    iterator.remove();
                } else {
                    isNeedRemove.set(false);
                }
            }
            //isNeedRemove.set(tree.getChildren().removeIf(treeSelect -> findTreeSelectNext(treeSelect, typeIds)));

        } else {
            if (typeIds.contains(tree.getKey())) {
                isNeedRemove.set(false);
            }
        }
        return isNeedRemove.get();
    }

    private void bindUserSelectWrapper(QueryWrapper<AsmsAssetFullInfo> queryWrapper, Long[] assetBindUserIds) {
        queryWrapper.and(qr -> {
            for (int i = 0; i < assetBindUserIds.length; i++) {
                if (i == 0) {
                    qr.eq(AsmsAssetFullInfo.BIND_USER_ID, assetBindUserIds[i]);
                } else qr.or().eq(AsmsAssetFullInfo.BIND_USER_ID, assetBindUserIds[i]);
            }
        });

    }

    private void addressSelectWrapper(QueryWrapper<AsmsAssetFullInfo> queryWrapper, Long[] addressIds) {
        queryWrapper.and(qr -> {
            for (int i = 0; i < addressIds.length; i++) {
                if (i == 0) {
                    qr.eq(AsmsAssetFullInfo.ADDRESS_ID, addressIds[i]);
                } else qr.or().eq(AsmsAssetFullInfo.ADDRESS_ID, addressIds[i]);
            }
        });

    }

    private void projectSelectWrapper(QueryWrapper<AsmsAssetFullInfo> queryWrapper, Long[] projectIds) {

        queryWrapper.and(qr -> {
            for (int i = 0; i < projectIds.length; i++) {
                if (i == 0) {
                    qr.eq(AsmsAssetFullInfo.PROJECT_ID, projectIds[i]);
                } else qr.or().eq(AsmsAssetFullInfo.PROJECT_ID, projectIds[i]);
            }
        });

    }

    private void ownDeptSelectWrapper(QueryWrapper<AsmsAssetFullInfo> queryWrapper, Long[] assetOwnIds) {

        queryWrapper.and(qr -> {
            for (int i = 0; i < assetOwnIds.length; i++) {
                if (i == 0) {
                    qr.eq(AsmsAssetFullInfo.OWN_DEPT_ID, assetOwnIds[i]);
                } else qr.or().eq(AsmsAssetFullInfo.OWN_DEPT_ID, assetOwnIds[i]);
            }
        });
    }

    @PreAuthorize
    @ApiOperation("根据资产区域Id获取资产列表")
    @GetMapping("/getAssetsByAddressId")
    public AjaxResult getAssetsByAddressId(@RequestParam("addressId") Long addressId) {
        List<AssetInfoVo> result = new ArrayList<>();
        List<AsmsAssetFullInfo> infoList = asmsAssetFullInfoService.list(new QueryWrapper<AsmsAssetFullInfo>()
                .eq(AsmsAssetFullInfo.ADDRESS_ID, addressId));
        infoList.forEach(item -> {
            AssetInfoVo vo = new AssetInfoVo();
            BeanUtils.copyProperties(item, vo);
            result.add(vo);
        });
        return AjaxResult.success(result);
    }

    @ApiOperation("按多种条件搜索资产")
    @GetMapping("/searchAsset")
    public TableDataInfo searchAsset(@RequestParam("searchValue") String searchValue) {
        QueryWrapper<AsmsAssetFullInfo> wrapper = new QueryWrapper<>();
        //管理员查看所有 其他角色查看属于自己部门的资产
        if (!SysUser.isAdmin(SecurityUtils.getUserId())) {
            Set<Long> userOwnDeptIds = tokenService.getUserOwnDeptIds();
            if (userOwnDeptIds.size() > 0) {
                wrapper.in(AsmsAssetFullInfo.OWN_DEPT_ID, userOwnDeptIds)
                        .in(AsmsAssetFullInfo.USE_DEPT_ID, userOwnDeptIds);
            }
        }
        wrapper.like(AsmsAssetFullInfo.ASSET_TYPE_NAME, searchValue)
                .or().like(AsmsAssetFullInfo.OWN_DEPT_NAME, searchValue)
                .or().like(AsmsAssetFullInfo.PROJECT_NAME, searchValue)
                .or().like(AsmsAssetFullInfo.BRAND_NAME, searchValue)
                .or().like(AsmsAssetFullInfo.ASSET_CODE, searchValue)
                .or().like(AsmsAssetFullInfo.ASSET_TEMPLATE_NAME, searchValue)
                .or().like(AsmsAssetFullInfo.MEASURE_UNIT, searchValue)
                .or().like(AsmsAssetFullInfo.SPECIFICATION, searchValue)
                .or().like(AsmsAssetFullInfo.ADDRESS_FULL_NAME, searchValue);
        startPage();
        List<AsmsAssetFullInfo> result = asmsAssetFullInfoService.list(wrapper);
        return getDataTable(result);
    }

    @ApiOperation("扫码查询资产")
    @GetMapping("/getAssetByScanCode")
    public AjaxResult getAssetByScanCode(@RequestParam("code") String code) {
        AsmsAssetFullInfo assetFullInfo = asmsAssetFullInfoService
                .getOne(new QueryWrapper<AsmsAssetFullInfo>()
                        .eq(AsmsAssetFullInfo.ASSET_CODE, code)
                        .or().eq(AsmsAssetFullInfo.SN, code));
        return AjaxResult.success(assetFullInfo);
    }

    @ApiOperation("扫码查询资产")
    @GetMapping("/getRAssetByScanCode")
    public R<AsmsAssetFullInfo> getRAssetByScanCode(@RequestParam("code") String code) {
        AsmsAssetFullInfo assetFullInfo = asmsAssetFullInfoService
                .getOne(new QueryWrapper<AsmsAssetFullInfo>()
                        .eq(AsmsAssetFullInfo.ASSET_CODE, code)
                        .or().eq(AsmsAssetFullInfo.SN, code));
        return R.ok(assetFullInfo);
    }

    @PostMapping("/getFullInfoByAssetIds")
    public R<List<AsmsAssetFullInfo>> getFullInfoByAssetIds(@RequestBody List<Long> assetIds){
        List<AsmsAssetFullInfo> list = asmsAssetFullInfoService.list(new QueryWrapper<AsmsAssetFullInfo>()
                .in(AsmsAssetFullInfo.ASSET_ID, assetIds));
        return R.ok(list);
    }


    @PostMapping("/getAssetsByOwnDeptIds")
    public R<List<AsmsAssetFullInfo>> getAssetsByOwnDeptIds(@RequestBody HashSet<Long> ownDeptIds) {
        List<AsmsAssetFullInfo> asmsAssetFullInfos = new ArrayList<>();
        if (ownDeptIds.size() != 0) {
            asmsAssetFullInfos = asmsAssetFullInfoService.list(new QueryWrapper<AsmsAssetFullInfo>()
                    .in(AsmsAssetFullInfo.OWN_DEPT_ID, ownDeptIds));
        }
        return R.ok(asmsAssetFullInfos);
    }

    @PostMapping("/importTime")
    public void importTime(MultipartFile file) {

        ExcelUtil<AssetFullInfoImportVo> util = new ExcelUtil<AssetFullInfoImportVo>(AssetFullInfoImportVo.class);
        List<AssetFullInfoImportVo> list = null;
        try {
            list = util.importExcel(file.getInputStream());
            Map<String, AssetFullInfoImportVo> importVoMap = list.stream().collect(Collectors.toMap(AssetFullInfoImportVo::getSn, item -> item, (a, b) -> b));

            Map<String, AsmsAssetFullInfo> fullInfoMap = asmsAssetFullInfoService.list().stream().collect(Collectors.toMap(AsmsAssetFullInfo::getSn, item -> item, (a, b) -> a));

            Map<Long, AsmsAssetFullInfo> assetIdFullInfoMap = asmsAssetFullInfoService.list().stream().collect(Collectors.toMap(AsmsAssetFullInfo::getAssetId, item -> item, (a, b) -> a));
            Map<Long, AsmsMaintenanceAsset> assetIdAssetMInfoMap = asmsMaintenanceAssetService.list().stream().collect(Collectors.toMap(AsmsMaintenanceAsset::getAssetId, item -> item));

            Map<String, AsmsMaintenanceAsset> assetSnAssetMInfoMap =new HashMap<>();

            assetIdAssetMInfoMap.forEach((key,value)-> assetSnAssetMInfoMap.put(assetIdFullInfoMap.get(key).getSn(),value));
            List<AsmsMaintenanceAsset> editAsmsMaintenanceAssets =new ArrayList<>();
            List<AsmsAssetFullInfo> editAsmsAssetFullInfos =new ArrayList<>();

            importVoMap.forEach((key,value)->{
                AsmsAssetFullInfo fullInfo = fullInfoMap.get(key);
                fullInfo.setStartUseTime(value.getStartUseTime());
                fullInfo.setEndUseTime(value.getEndUseTime());
                editAsmsAssetFullInfos.add(fullInfo);
                AsmsMaintenanceAsset asmsMaintenanceAsset = assetSnAssetMInfoMap.get(key);
                asmsMaintenanceAsset.setStartUseTime(value.getStartUseTime());
                asmsMaintenanceAsset.setEndUseTime(value.getEndUseTime());
                editAsmsMaintenanceAssets.add(asmsMaintenanceAsset);
            });
            asmsAssetFullInfoService.updateBatchById(editAsmsAssetFullInfos);
            asmsMaintenanceAssetService.updateBatchById(editAsmsMaintenanceAssets);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

//    @GetMapping("/getIotMeterList")
//    @ApiOperation("电表水表列表")
//    public TableDataInfo getIotMeterList(@RequestParam(value = "deptId",required = false) Long deptId,
//                                         @RequestParam(value ="addressName",required = false)String addressName,
//                                         @RequestParam(value ="addressId",required = false)String addressId,
//                                         @RequestParam(value ="assetTypeId",required = false)String assetTypeId){
//
//        if(deptId == null){
//            deptId = tokenService.getLoginUser().getDeptid();
//        }
//        startPage();
//        Long finalDeptId = deptId;
//        List<AsmsAssetFullInfo> list = asmsAssetFullInfoService.list(new QueryWrapper<AsmsAssetFullInfo>().and(QueryWrapper -> QueryWrapper.like(AsmsAssetFullInfo.U_ANCESTORS, "," + finalDeptId + ",").or().
//                eq(AsmsAssetFullInfo.U_PARENT_ID, finalDeptId).or().eq(AsmsAssetFullInfo.USE_DEPT_ID, finalDeptId)).
//                and(QueryWrapper -> QueryWrapper.like(addressId != null, AsmsAssetFullInfo.ADDRESS_ANCESTORS, "," + addressId + ",").or().
//                        eq(addressId != null, AsmsAssetFullInfo.ADDRESS_PARENT_ID, addressId).or().
//                        eq(addressId != null, AsmsAssetFullInfo.ADDRESS_ID, addressId)).
//                and(QueryWrapper -> QueryWrapper.like(assetTypeId != null, AsmsAssetFullInfo.ASSET_TYPE_ANCESTORS, "," + assetTypeId + ",").or().
//                        eq(assetTypeId != null, AsmsAssetFullInfo.TYPE_PARENT_ID, assetTypeId).or().
//                        eq(assetTypeId != null, AsmsAssetFullInfo.ASSET_TYPE_ID, assetTypeId))
//                .like(addressName != null, AsmsAssetFullInfo.ADDRESS_NAME, addressName));
//
//        return getDataTable(list);
//    }

//    @ApiOperation("导出电表树表报表")
//    @GetMapping("/exportInstallModle")
//    public void exportR(HttpServletResponse response,@RequestParam(value = "",required = false)Long addressId,
//                        @RequestParam(value = "",required = false)Long assetTypeId,
//                        @RequestParam(value = "",required = false)Long startTime,
//                        @RequestParam(value = "",required = false)Long endTime) throws IOException {
//
//        List<AsmsAssetFullInfo> fullInfoList = asmsAssetFullInfoService.list(new QueryWrapper<AsmsAssetFullInfo>().eq(assetTypeId != null, AsmsAssetFullInfo.ASSET_TYPE_ID, assetTypeId).
//                and(QueryWrapper -> QueryWrapper.like(addressId != null, AsmsAssetFullInfo.ADDRESS_ANCESTORS, "," + addressId + ",").or().
//                        eq(addressId != null, AsmsAssetFullInfo.ADDRESS_PARENT_ID, addressId).or().
//                        eq(addressId != null, AsmsAssetFullInfo.ADDRESS_ID, addressId)));
//
//        List<Long> assetIds = new LinkedList<>();
//        for(AsmsAssetFullInfo a:fullInfoList){
//            assetIds.add(a.getAssetId());
//        }
//        HashMap<Long, MeterReadVo> meterReadVoMap = remoteIotService.getMeterReadList(assetIds, startTime, endTime, assetTypeId).getData();
//
//        if(meterReadVoMap == null){
//           return;
//        }
//
//        List<MeterExcelVo> excelList = new LinkedList<>();
//        for(AsmsAssetFullInfo a:fullInfoList){
//            MeterReadVo meterReadVo = meterReadVoMap.get(a.getAssetId());
//            if( meterReadVo != null){
//               MeterExcelVo excelVo = new MeterExcelVo();
//               excelVo.setAddressName(a.getAddressName());
//               excelVo.setNickName(a.getNickName());
//               excelVo.setPhoneNUmber(a.getPhonenumber());
//               excelVo.setEndDay(meterReadVo.getEndReadDay());
//               excelVo.setEndRead(meterReadVo.getEndReadData());
//               excelVo.setStartDay(meterReadVo.getStartReadDay());
//               excelVo.setStartRead(meterReadVo.getStartReadData());
//
//               excelList.add(excelVo);
//           }
//        }
//
//        ExcelUtil<MeterExcelVo> util = new ExcelUtil<>(MeterExcelVo.class);
//        List<MeterExcelVo> list = new LinkedList<>();
//
//        MeterExcelVo meterExcelVo = new MeterExcelVo();
//        list.add(meterExcelVo);
//
//        util.exportExcel(response, list, "任务完成情况");
//    }

}
